package com.android.kotlincoroutinemvvmdemo.hook

import android.content.Context
import android.os.Handler
import android.os.Message
import android.util.Log
import android.widget.Toast
import androidx.annotation.StringRes
import java.lang.reflect.Field

object HookToast {

    private const val TAG = "HookToast"

    private var sField_TN: Field? = null
    private var sField_TN_Handler: Field? = null

    private var mToast: Toast? = null

    fun show(context: Context, message: CharSequence, duration: Int) {
        if (mToast == null) {
            mToast = Toast.makeText(context.applicationContext, message, duration)
            hook(mToast!!)
        } else {
            mToast?.setText(message)
            mToast?.duration = duration
        }
        mToast?.show()
    }

    fun show(context: Context, @StringRes resId: Int, duration: Int) {
        if (mToast == null) {
            mToast = Toast.makeText(context.applicationContext, resId, duration)
            hook(mToast!!)
        } else {
            mToast?.setText(context.getString(resId))
            mToast?.duration = duration
        }
        mToast?.show()
    }

    private fun hook(toast: Toast) {
        try {
            sField_TN = FieldUtil.getField(Toast::class.java,"mTN")
            //API33之后不允许反射获取mTN
            //sField_TN = Toast::class.java.getDeclaredField("mTN")
            sField_TN_Handler = FieldUtil.getField(sField_TN?.type, "mHandler")
            //sField_TN_Handler = sField_TN?.type!!::class.java.getDeclaredField("mHandler")
            val tn = sField_TN?.get(toast)
            val handler = sField_TN_Handler?.get(tn) as? Handler
            sField_TN_Handler?.set(tn, ReplaceHandler(handler))
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
    }

    private class ReplaceHandler(handler: Handler?) : Handler() {
        private val mHandler = handler
        override fun dispatchMessage(msg: Message) {
            try {
                super.dispatchMessage(msg)
                Log.d(TAG, "override fun dispatchMessage")
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            mHandler?.handleMessage(msg)
            Log.d(TAG, "override fun handleMessage")
        }
    }
}